#include "../log/logger.hpp"
#include <iostream>
#include <thread>
#include <chrono>
#include <vector>

/**
 * 异步日志使用示例
 * 演示如何配置和使用异步日志器，以及异步日志的性能优势
 */

using namespace tclog;

void demonstrateBasicAsyncLogging() {
    std::cout << "\n=== 基础异步日志示例 ===" << std::endl;
    
    // 创建异步日志器
    LocalLoggerBuilder builder;
    builder.buildLoggerName("async_logger");
    builder.buildLoggerLevel(LogLevel::value::DEBUG);
    builder.buildLoggerType(Logger::Type::LOGGER_ASYNC);  // 设置为异步类型
    builder.buildSink<StdoutSink>();
    builder.buildSink<FileSink>("./logs/async_basic.log");
    
    auto logger = builder.build();
    
    std::cout << "开始异步日志输出..." << std::endl;
    
    // 快速输出大量日志
    for (int i = 1; i <= 10; ++i) {
        logger->debug(__FILE__, __LINE__, "异步调试日志 #{}", i);
        logger->info(__FILE__, __LINE__, "异步信息日志 #{}", i);
        logger->warn(__FILE__, __LINE__, "异步警告日志 #{}", i);
    }
    
    std::cout << "异步日志输出完成（注意：实际写入可能仍在后台进行）" << std::endl;
    
    // 等待一段时间确保异步日志完成写入
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
}

void demonstrateAsyncVsSyncPerformance() {
    std::cout << "\n=== 异步vs同步性能对比示例 ===" << std::endl;
    
    const int LOG_COUNT = 1000;
    
    // 测试同步日志器性能
    {
        LocalLoggerBuilder syncBuilder;
        syncBuilder.buildLoggerName("sync_perf_logger");
        syncBuilder.buildLoggerLevel(LogLevel::value::INFO);
        syncBuilder.buildLoggerType(Logger::Type::LOGGER_SYNC);  // 同步类型
        syncBuilder.buildSink<FileSink>("./logs/sync_performance.log");
        
        auto syncLogger = syncBuilder.build();
        
        auto start = std::chrono::high_resolution_clock::now();
        
        for (int i = 0; i < LOG_COUNT; ++i) {
            syncLogger->info(__FILE__, __LINE__, "同步日志性能测试 #{} - 这是一条用于性能测试的日志消息", i);
        }
        
        auto end = std::chrono::high_resolution_clock::now();
        auto syncDuration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
        
        std::cout << "同步日志器写入 " << LOG_COUNT << " 条日志耗时: " << syncDuration.count() << "ms" << std::endl;
    }
    
    // 测试异步日志器性能
    {
        LocalLoggerBuilder asyncBuilder;
        asyncBuilder.buildLoggerName("async_perf_logger");
        asyncBuilder.buildLoggerLevel(LogLevel::value::INFO);
        asyncBuilder.buildLoggerType(Logger::Type::LOGGER_ASYNC);  // 异步类型
        asyncBuilder.buildSink<FileSink>("./logs/async_performance.log");
        
        auto asyncLogger = asyncBuilder.build();
        
        auto start = std::chrono::high_resolution_clock::now();
        
        for (int i = 0; i < LOG_COUNT; ++i) {
            asyncLogger->info(__FILE__, __LINE__, "异步日志性能测试 #{} - 这是一条用于性能测试的日志消息", i);
        }
        
        auto end = std::chrono::high_resolution_clock::now();
        auto asyncDuration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
        
        std::cout << "异步日志器写入 " << LOG_COUNT << " 条日志耗时: " << asyncDuration.count() << "ms" << std::endl;
        
        // 等待异步日志完成写入
        std::this_thread::sleep_for(std::chrono::milliseconds(200));
        std::cout << "（异步日志后台写入已完成）" << std::endl;
    }
}

void demonstrateMultiThreadAsyncLogging() {
    std::cout << "\n=== 多线程异步日志示例 ===" << std::endl;
    
    // 创建异步日志器
    LocalLoggerBuilder builder;
    builder.buildLoggerName("multithread_async_logger");
    builder.buildLoggerLevel(LogLevel::value::DEBUG);
    builder.buildLoggerType(Logger::Type::LOGGER_ASYNC);
    builder.buildSink<StdoutSink>();
    builder.buildSink<FileSink>("./logs/multithread_async.log");
    
    auto logger = builder.build();
    
    const int THREAD_COUNT = 4;
    const int LOGS_PER_THREAD = 50;
    
    std::vector<std::thread> threads;
    
    auto start = std::chrono::high_resolution_clock::now();
    
    // 启动多个线程同时写日志
    for (int t = 0; t < THREAD_COUNT; ++t) {
        threads.emplace_back([logger, t, LOGS_PER_THREAD]() {
            for (int i = 0; i < LOGS_PER_THREAD; ++i) {
                logger->info(__FILE__, __LINE__, "线程{} 日志#{} - 多线程异步日志测试", t, i);
                
                // 模拟一些工作
                std::this_thread::sleep_for(std::chrono::microseconds(100));
            }
        });
    }
    
    // 等待所有线程完成
    for (auto& thread : threads) {
        thread.join();
    }
    
    auto end = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
    
    std::cout << THREAD_COUNT << " 个线程各写入 " << LOGS_PER_THREAD 
              << " 条日志，总耗时: " << duration.count() << "ms" << std::endl;
    
    // 等待异步日志完成写入
    std::this_thread::sleep_for(std::chrono::milliseconds(300));
    std::cout << "多线程异步日志写入完成" << std::endl;
}

void demonstrateAsyncWithRollSink() {
    std::cout << "\n=== 异步日志配合滚动文件示例 ===" << std::endl;
    
    // 创建异步滚动文件日志器
    LocalLoggerBuilder builder;
    builder.buildLoggerName("async_roll_logger");
    builder.buildLoggerLevel(LogLevel::value::INFO);
    builder.buildLoggerType(Logger::Type::LOGGER_ASYNC);
    // 设置较小的文件大小以便观察滚动效果
    builder.buildSink<RollSink>("./logs/async_roll-", 2048);  // 2KB滚动
    
    auto logger = builder.build();
    
    std::cout << "开始异步滚动文件日志输出..." << std::endl;
    
    // 输出大量日志触发文件滚动
    for (int i = 1; i <= 100; ++i) {
        logger->info(__FILE__, __LINE__, 
            "异步滚动日志 #{:03d} - 这是一条比较长的日志消息，用于测试异步日志器配合滚动文件的功能，"
            "当文件大小超过设定阈值时会自动创建新文件", i);
        
        if (i % 20 == 0) {
            std::cout << "已输出 " << i << " 条日志..." << std::endl;
        }
    }
    
    std::cout << "异步滚动日志输出完成" << std::endl;
    
    // 等待异步日志完成写入
    std::this_thread::sleep_for(std::chrono::milliseconds(500));
    std::cout << "请检查 ./logs/async_roll-*.log 文件" << std::endl;
}

void demonstrateAsyncLoggerLifecycle() {
    std::cout << "\n=== 异步日志器生命周期示例 ===" << std::endl;
    
    {
        // 在作用域内创建异步日志器
        LocalLoggerBuilder builder;
        builder.buildLoggerName("lifecycle_async_logger");
        builder.buildLoggerLevel(LogLevel::value::DEBUG);
        builder.buildLoggerType(Logger::Type::LOGGER_ASYNC);
        builder.buildSink<FileSink>("./logs/lifecycle_async.log");
        
        auto logger = builder.build();
        
        std::cout << "异步日志器已创建，开始输出日志..." << std::endl;
        
        for (int i = 1; i <= 20; ++i) {
            logger->info(__FILE__, __LINE__, "生命周期测试日志 #{}", i);
        }
        
        std::cout << "即将离开作用域，异步日志器将被销毁..." << std::endl;
        
        // 在日志器销毁前稍作等待，确保异步日志有时间写入
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }
    
    std::cout << "异步日志器已销毁，后台线程已停止" << std::endl;
    
    // 再等待一段时间确保所有异步操作完成
    std::this_thread::sleep_for(std::chrono::milliseconds(200));
}

int main() {
    std::cout << "=== BoltLog 异步日志使用示例 ===" << std::endl;
    
    // 演示各种异步日志使用场景
    demonstrateBasicAsyncLogging();
    demonstrateAsyncVsSyncPerformance();
    demonstrateMultiThreadAsyncLogging();
    demonstrateAsyncWithRollSink();
    demonstrateAsyncLoggerLifecycle();
    
    std::cout << "\n=== 异步日志示例完成 ===" << std::endl;
    std::cout << "异步日志的优势：" << std::endl;
    std::cout << "1. 更高的性能 - 日志写入不阻塞主线程" << std::endl;
    std::cout << "2. 更好的并发性 - 多线程环境下表现优异" << std::endl;
    std::cout << "3. 更平滑的用户体验 - 不会因为日志I/O影响程序响应" << std::endl;
    std::cout << "\n请检查 ./logs/ 目录下生成的异步日志文件" << std::endl;
    
    return 0;
}